package com.atu.poker.thread;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.atu.poker.service.RoomInfoService;
import com.atu.poker.service.RoomSeatService;
import com.atu.poker.service.UserInfoService;

import server.MainSocket;

public class SocketThread implements Runnable {
	private Socket socket = null;
	private BufferedReader bufferedReader = null;
	private OutputStream outputStream = null;
	private JSONObject jsonObject;
	private UserInfoService userInfoService = new UserInfoService();
	private RoomInfoService roomInfoService = new RoomInfoService();
	private RoomSeatService roomSeatService = new RoomSeatService();
	private JSONObject loginJson;
	private Timer timer;
	private Timer loginTimer;
	private String userId;
	private String reqType;
	private static Logger logger = LogManager.getLogger(SocketThread.class);

	public SocketThread(Socket socket) throws IOException {
		this.socket = socket;
		this.bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		this.outputStream = socket.getOutputStream();
	}

	@Override
	public void run() {
		timer = new Timer();

		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				try {
					outputStream.write(("111" + "\n").getBytes("utf-8"));
				} catch (IOException e) {
					if (outputStream != null) {
						try {
							outputStream.close();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
					}
					timer.cancel();
					MainSocket.sockets.remove(socket);
					e.printStackTrace();
				}
			}
		}, 1000, 6000);

		String context = null;
		while ((context = readFromClient()) != null) {

			logger.debug(context);
			jsonObject = JSONObject.parseObject(context.toString());
			reqType = jsonObject.getString("reqType");

			this.selectReqType(reqType);

			// for (Iterator<Socket> iterator = MainSocket.sockets.iterator();
			// iterator.hasNext();) {
			// System.out.println(iterator);
			// Socket socket = iterator.next();
			// try {
			// printStream.println(("返回测试"));
			// } catch (Exception e) {
			// userInfoDAO.changeUserStatus("150525b903a340e0a23c9a18653c98e4", "0");
			// System.out.println("删除【" + socket + "】");
			// }
			// }
		}
	}

	private void selectReqType(String reqType) {
		if ("loginReq".equals(reqType)) {
			this.loginConfirm();
		} else if ("exitReq".equals(reqType)) {
			this.exitConfirm();
		} else if ("createRoomReq".equals(reqType)) {
			this.createRoom();
		} else if ("joinRoomReq".equals(reqType)) {
			this.joinRoom(jsonObject.getString("roomId"),jsonObject.getString("userId"));
		} else if ("sendSeatReq".equals(reqType)) {
			this.seadSeat();
		} else if ("closeRoomReq".equals(reqType)) {
			this.closeRoom();
		} else if ("settlementReq".equals(reqType)) {
			this.settlement();
		}else if ("getRoomListReq".equals(reqType)) {
			this.getNotCloseRoomList(jsonObject.getString("filterRoom"));
		} else if ("dealReq".equals(reqType)) {
			this.deal();
		} else if ("getDealCardReq".equals(reqType)) {
			this.getDealCard();
		} else if ("getCardReq".equals(reqType)) {
			this.getCard();
		} else if ("nextPlayerReq".equals(reqType)) {
			this.nextPlayer();
		} else if ("openCardReq".equals(reqType)) {
			this.openCard();
		} else if ("sendEscrowReq".equals(reqType)) {
			this.sendEscrow();
		} else if ("firstAddReq".equals(reqType)) {
			this.firstAddConfirm();
		} else if ("secondAddReq".equals(reqType)) {
			this.secondAddConfirm();
		} else if ("firstUpReq".equals(reqType)) {
			this.firstUpConfirm();
		} else if ("secondUpReq".equals(reqType)) {
			this.secondUpConfirm();
		}else if ("bankerSettlementReq".equals(reqType)) {
			this.bankerSettlement();
		}
	}

	private void bankerSettlement() {
		roomSeatService.bankerSettlement(jsonObject.getString("seatId"),jsonObject.getString("chip"));
	}

	private void settlement() {
		roomSeatService.getSettlementChip(jsonObject.getString("roomId"),jsonObject.getString("bankerChip"));
	}

	private void getDealCard() {
		roomSeatService.getBankerDealCard(jsonObject.getString("seatId"));
	}

	private void sendEscrow() {
		roomSeatService.sendSeatEscrow(jsonObject.getString("seatId"), jsonObject.getString("escrow"));
	}

	private void openCard() {
		roomSeatService.openCard(jsonObject.getString("seatNo"), jsonObject.getString("roomId"));
	}

	private void nextPlayer() {
		roomSeatService.nextPlayerPointer(jsonObject.getString("seatId"));
	}

	private void getCard() {
		roomSeatService.sendCard(jsonObject.getString("seatId"));
	}

	private void closeRoom() {
		roomInfoService.closeRoom(jsonObject.getString("seatId"));
	}

	private void seadSeat() {
		String seatId = jsonObject.getString("seatId");
		MainSocket.seatMap.map.put(seatId, outputStream);
		logger.debug(MainSocket.seatMap.map);
		try {
			outputStream.write((roomSeatService.getSeat(seatId) + "\n").getBytes("utf-8"));
		} catch (Exception e) {
			logger.error("seadSeat返回错误");
			e.printStackTrace();
		}
	}

	private void joinRoom(String roomId,String userId) {
		try {
			synchronized (MainSocket.object) {
				Thread.currentThread().sleep(500);
				outputStream.write(
						(roomInfoService.joninRoom(roomId, userId) + "\n")
								.getBytes("utf-8"));
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("joinRoom返回错误");
		}

	}

	private void deal() {
		roomSeatService.getDeal(jsonObject.getString("roomId"));
	}

	private void getNotCloseRoomList(String filterRoom) {
		try {
			outputStream.write((roomInfoService.getNotCloseRoomList(filterRoom) + "\n").getBytes("utf-8"));
		} catch (Exception e) {
			logger.error("getRoomListReq返回错误");
			e.printStackTrace();
		}
	}

	private void createRoom() {
		try {
			outputStream.write(
					(roomInfoService.createRoom(jsonObject.getString("userId"), "", jsonObject.getString("upperChip"),
							jsonObject.getString("lowerChip"), jsonObject.getString("userLimit")) + "\n")
									.getBytes("utf-8"));
		} catch (IOException e) {
			logger.error("createRoomReq返回错误");
			e.printStackTrace();
		}
	}

	private void firstUpConfirm() {
		try {
			outputStream
					.write((userInfoService.upConfirmEmail(jsonObject.getString("email")) + "\n").getBytes("utf-8"));
		} catch (IOException e) {
			logger.error("firstUpReq返回错误");
			e.printStackTrace();
		}
	}

	private void secondUpConfirm() {
		try {
			outputStream.write((userInfoService.upUserInfo(jsonObject.getString("email"),
					jsonObject.getString("emailCode"), jsonObject.getString("userPwd")) + "\n").getBytes("utf-8"));
		} catch (IOException e) {
			logger.error("secondUpReq返回错误");
			e.printStackTrace();
		}
	}

	private void loginConfirm() {
		// 得到userInfoService返回的json数据，解析出来
		loginJson = JSONObject.parseObject(
				userInfoService.loginUser(jsonObject.getString("email"), jsonObject.getString("userPwd")).toString());
		if ("305".equals(loginJson.getString("respType"))) {
			userId = loginJson.getJSONObject("userInfo").getString("userId");
			if (timer != null) {
				timer.cancel();
			}
			loginTimer = new Timer();
			loginTimer.schedule(new TimerTask() {
				@Override
				public void run() {
					try {
						if (!socket.isClosed()) {
							// logger.debug("定时向客户端发送请求");
							/*
							 * Map<String, Object> map = new HashMap<>(); map.put("respType", "111");
							 */
							// 不需要以json方式传输，浪费资源
							outputStream.write(("111" + "\n").getBytes("utf-8"));
						}
					} catch (IOException e) {
						if (outputStream != null) {
							try {
								outputStream.close();
							} catch (IOException e1) {
								e1.printStackTrace();
							}
						}
						userInfoService.changeLoginStatus(userId, "0");
						MainSocket.sockets.remove(socket);
						if (loginTimer != null) {
							loginTimer.cancel();
						}
						logger.error("loginTimer.schedule(new TimerTask() {错误");
						e.printStackTrace();
					}
				}
			}, 1000, 6000);

		}
		try {
			outputStream.write((loginJson + "\n").getBytes("utf-8"));
		} catch (IOException e) {
			logger.error("loginReq返回错误");
			e.printStackTrace();
		}
	}

	private void exitConfirm() {
		userInfoService.changeLoginStatus(userId, "0");
		if (loginTimer != null) {
			loginTimer.cancel();
		}
	}

	/**
	 * 第二次注册请求，根据邮箱验证码是否正确，正确则注册成功
	 * 
	 * @param reqType
	 */
	private void secondAddConfirm() {
		try {
			outputStream
					.write((userInfoService.addUserInfo(jsonObject.getString("userName"), jsonObject.getString("email"),
							jsonObject.getString("emailCode"), jsonObject.getString("userPwd")) + "\n")
									.getBytes("utf-8"));
		} catch (IOException e) {
			logger.error("secondAddReq返回错误");
			e.printStackTrace();
		}
	}

	/**
	 * 第一次注册用户请求，验证用户名和邮箱是否存在，若不存在，则发送验证码至邮箱
	 * 
	 * @param reqType
	 */
	private void firstAddConfirm() {
		try {
			outputStream.write(
					(userInfoService.addConfirmEmail(jsonObject.getString("userName"), jsonObject.getString("email"))
							+ "\n").getBytes("utf-8"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private String readFromClient() {
		try {
			return bufferedReader.readLine();
		} catch (IOException e) {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			userInfoService.changeLoginStatus(userId, "0");
			MainSocket.sockets.remove(socket);
			if (loginTimer != null) {
				loginTimer.cancel();
			}
			logger.error("bufferedReader.readLine();错误");
			e.printStackTrace();
			MainSocket.sockets.remove(socket);
		}
		return null;
	}
}
